import GameWx from "./GameWx";
import GameEvent from "./GameEvent";
import GEnemy from "./gameobj/GEnemy";
import GUniverse from "./gameobj/GUniverse";
import Gobj from "./gameobj/Gobj";
import VEnemy from "./gameobj/VEnemy";
import Vobj from "./gameobj/Vobj";
import VTower from "./gameobj/VTower";
import VBullet from "./gameobj/VBullet";
import HomeUI from "./HomeUI";

export default class GameCore {

    sfn = 50;
    cfn = 1000 / 60;
    cfps = 60;

    actionMap = {};
    st = 0;
    ct = 0;

    fms = 0;
    sf = 0;

    lf = 0;
    stop_f = false;

    max_cf = 60 * 60 * 3;

    viewMap0 = {};
    viewMap1 = {};

    ssf = 0;
    slf = 0;
    sfms = 0;

    csf = 0;
    clf = 0;
    cfms = 0;

    /**平行宇宙1 */
    un1: GUniverse = new GUniverse(1);
    /**平行宇宙2 */
    un2: GUniverse = new GUniverse(2);

    initGame() {

        this.csf = 0;
        this.clf = 0;
        this.cfms = 0;

        this.ssf = 0;
        this.slf = 0;
        this.sfms = 0;

        this.viewMap0 = {};
        this.viewMap1 = {};

        this.stop_f = false;
        this.actionMap = {};
        this.st = Date.now();
        this.ct = 0;
        this.fms = 0;
        this.sf = 0;

        this.cfn = 1000 / this.cfps;
        this.lf = 0;
        Laya.stage.clearTimer(this, this.efe);

        this.un1.init_();
        this.un2.init_();
    }




    efe() {
        var ct = Date.now();
        var dt = ct - this.st;
        var kf = Math.floor(dt / this.cfn) + 1;
        var fms = 0;
        while (this.lf < kf) {
            var sf = Math.floor(this.lf / 3);
            var keyf = false;
            if (this.lf % 3 == 0) {
                fms = sf * 50;
                keyf = true;
            }
            else if (this.lf % 3 == 1) {
                fms = sf * 50 + 16;
            }
            else if (this.lf % 3 == 2) {
                fms = sf * 50 + 33;
            }
            this.lf++;
            this.gameAc2(sf + 1, this.lf, fms, keyf);
        }
        this.viewExe();
    }


    stop() {
        Laya.stage.clearTimer(this, this.efe);
    }

    start() {
        Laya.stage.frameLoop(1, this, this.efe);
    }

    /**
     * 帧同步驱动
     * @param res 
     */
    syncFrame(res: { frameId: number, actionList: string[] }) {
        if (res.frameId == 1) {
            GameWx.I.event(GameEvent.Event_WX_Game_Start);
            this.initGame();
            this.st = Date.now();
            Laya.stage.frameLoop(1, this, this.efe);
        }

        this.ct = Date.now();
        this.fms = (res.frameId - 1) * this.sfn;
        var dt = this.ct - this.st;
        //校正时间戳
        var tt = (this.fms - dt);
        if (tt >= 1) {
            this.st -= tt;
        }

        this.sf = res.frameId;
        if (res.actionList && res.actionList.length > 0) { //下个逻辑帧执行
            var key = "ac_" + (this.sf + 1);
            this.actionMap[key] = res.actionList;
            //console.log(key," ",res.actionList);
        }
        var lf = (this.sf - 1) * 3 + 1;
        if (!this.stop_f) {
            this.gameAc1(this.sf, lf, this.fms, true);
            this.gameAc1(this.sf, lf + 1, this.fms + 16);
            this.gameAc1(this.sf, lf + 2, this.fms + 33);
        }
    }


    gameAc1(sf: number, lf: number, fms: number, keyf: boolean = false) {
        this.ssf = sf;
        this.slf = lf;
        this.sfms = fms;

        if (keyf) {
            var key = "ac_" + sf;
            if (this.actionMap[key]) {
                if (this.csf >= this.ssf && !this.un2.actionMap[key]) {
                    console.log(" 校验 然后时间倒流 ", key, this.ssf, this.csf);
                    // this.e2.x = this.e1.x;
                    // this.e2.y = this.e1.y;
                    // this.e2.speed = this.e1.speed;
                    this.un2.syncTime(this.un1);
                    this.lf = lf;
                    this.gameAc2(sf, lf, fms, keyf);
                    // for (let i = 0; i < 10000; i++) {
                    //     console.log(i);                        
                    // }
                    // console.log(this.viewMap0 );
                }
                this.un1.actionMap[key] = this.actionMap[key];
                // if(this.e1.speed==2){
                //     this.e1.speed=1;
                // }else{
                //     this.e1.speed=2;
                // }
            }
        }

        this.un1.timeline(sf, lf, fms, keyf);
        //console.log('ac1 :: ',sf,lf,fms);
        // if(!this.e1.die)
        // this.e1.efe(lf,"e1");
        if (lf == this.max_cf) {
            this.stop_f = true;
        }
    }

    gameAc2(sf: number, lf: number, fms: number, keyf: boolean) {
        //console.log('ac2 :: ',sf,lf,fms);
        this.csf = sf;
        this.clf = lf;
        this.cfms = fms;

        if (keyf) {
            var key = "ac_" + sf;
            if (this.actionMap[key]) {
                // if(this.e2.speed==2){
                //     this.e2.speed=1;
                // }else{
                //     this.e2.speed=2;
                // }
                this.un2.actionMap[key] = this.actionMap[key];
            }
        }
        this.un2.timeline(sf, lf, fms, keyf);

        // if(!this.e2.die)
        // this.e2.efe(lf,"e2");

        if (lf == this.max_cf) {
            this.stop();
        }
    }



    public getView(key: string) {
        var o = this.viewMap0[key];
        delete this.viewMap0[key];
        return o;
    }

    public setView(key: string, o: Vobj) {
        this.viewMap1[key] = o;
    }

    public exeView(arr:Gobj[]){
        for (let i = 0; i < arr.length; i++) {
            const boj = arr[i];
            if (boj.id != 0) {
                var o = this.getView(boj.key) as Vobj;
                if (o) {
                    o.efe(boj, this.clf,this.cfms);
                } else {                    
                    if(boj.type == Gobj.GEnemy){
                        o = new VEnemy();
                    }
                    else if(boj.type == Gobj.GTower){
                        o = new VTower();                        
                    }                    
                    else if(boj.type == Gobj.GBullet){
                        o = new VBullet();                        
                    }
                    o.id = boj.id;
                    o.init(boj);
                    o.efe(boj, this.clf, this.cfms);
                    Laya.stage.addChild(o);
                }
                this.setView(boj.key, o);
            }
        }

        
    }

    viewExe() {

        //执行怪物表渲染
        var arr: Gobj[] = this.un2.gm.getPlayer(1).monsterMap.objArr;
        this.exeView(arr);
        var arr: Gobj[] = this.un2.gm.getPlayer(2).monsterMap.objArr;
        this.exeView(arr);

        //执行炮塔表渲染
        var arr: Gobj[] = this.un2.gm.getPlayer(1).towerMap.objArr;
        this.exeView(arr);
        var arr: Gobj[] = this.un2.gm.getPlayer(2).towerMap.objArr;
        this.exeView(arr);

        //执行子弹表渲染
        var arr: Gobj[] = this.un2.gm.getPlayer(1).bulletMap.objArr;
        this.exeView(arr);
        var arr: Gobj[] = this.un2.gm.getPlayer(2).bulletMap.objArr;
        this.exeView(arr);

        //删除不需要的渲染对象
        for (const key in this.viewMap0) {
            //if (this.viewMap0.hasOwnProperty(key)) {
                const ve = this.viewMap0[key];
                ve.destory();
            //}
        }
        this.viewMap0 = this.viewMap1;
        this.viewMap1 = {};

        var pss = "player1 hp= "
         + this.un2.gm.getPlayer(1).hp
         + "      ::      player2 hp= "
         + this.un2.gm.getPlayer(2).hp;
        HomeUI.I.label3.text = pss;
    }



    private static gcore_: GameCore
    public static get I(): GameCore {
        if (!this.gcore_) {
            this.gcore_ = new GameCore();
        }
        return this.gcore_;
    }
    private constructor() { }
}